package com.george.order.loadbalance;


import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @title: LeastConnectionsLoadBalancer.java
 * @description: 负载均衡算法-最小连接数（Least Connections）
 * @author: George.Dong
 * @date: 2024/5/30 12:08
 */
public class LeastConnectionsLoadBalancer {
    /**
     * 服务器列表
     */
    private List<WeightServer> servers;
    /**
     * 服务器与其当前连接数的映射
     */
    private Map<String, Integer> serverConnections;

    /**
     * 构造函数，初始化服务器列表和它们的连接数。
     *
     * @param servers 服务器列表，不能为null。
     */
    public LeastConnectionsLoadBalancer(List<WeightServer> servers) {
        this.servers = servers;
        this.serverConnections = new HashMap<>();
        for (WeightServer server : servers) {
            serverConnections.put(server.getName(), server.getCurrentConnect());
        }
    }

    /**
     * 获取下一个应服务的服务器。
     * 这个方法会遍历服务器列表，选择当前连接数最少的服务器。
     *
     * @return 返回连接数最少的服务器
     */
    public synchronized WeightServer getNextServer() {
        WeightServer leastConnectedServer = null;
        int minConnections = Integer.MAX_VALUE;
        for (WeightServer server : servers) {
            int connections = serverConnections.get(server.getName());
            if (connections < minConnections) {
                minConnections = connections;
                leastConnectedServer = server;
            }
        }
        serverConnections.put(leastConnectedServer.getName(), minConnections + 1);
        return leastConnectedServer;
    }


    /**
     * 主函数，用于演示负载均衡器的工作流程。
     * 创建一个负载均衡器实例，并模拟请求的分发与完成。
     */
    public static void main(String[] args) {
        // 初始化服务器列表，指定当前服务器连接数，模拟分发
        List<WeightServer> servers = Arrays.asList(new WeightServer("Server1", 0, 0), new WeightServer("Server2", 0, 100));
        LeastConnectionsLoadBalancer lb = new LeastConnectionsLoadBalancer(servers);

        for (int i = 0; i < 10; i++) {
            WeightServer server = lb.getNextServer();
            String clientIp = "192.168.0.13" + i;
            System.out.println("Client IP: " + clientIp + " -> Server: " + server.getName());
        }
    }
}
